<!-- 控件视图-自由容器选中框 -->
<template>
    <div
        v-if="showSelectDox"
        class="widget-view-free-vessel-selection"
        :style="selectBoxStyle"
        @mousedown.stop="onSelectBoxDraggable"
        @contextmenu.prevent.stop="onSelectBoxContextmenu"
        @click.stop="() => {}"
    >
        <widget-view-border />
    </div>
</template>

<script>
import { defineComponent, toRefs, ref, computed, watch, nextTick } from 'vue'
import useWidget from '@/libs/edit/widgetData'
import useWidgetView from '@/libs/edit/widgetView'
import usePageHistory from '@/libs/edit/pageHistory'
import usePhoneZoom from '@/libs/edit/phoneZoom'
import { openWidgetContextmenu } from '@/components/edit/widget-contextmenu'
import WidgetViewBorder from '../widget-view-border'
export default defineComponent({
    name: 'WidgetViewFreeVesselCheckbox',
    components: {
        WidgetViewBorder
    },
    props: {
        // 选中的控件id集合
        widgetIds: {
            type: Array,
            default: () => ([])
        },
        // 父容器dom
        parentDom: {
            type: Object,
            default: () => ({})
        }
    },
    setup(props, { emit }) {
        const { widgetIds, parentDom } = toRefs(props)

        const {
            widgetListFlat
        } = useWidget()

        const {
            onAddPageHistory
        } = usePageHistory()

        const {
            getWidgetViewDom
        } = useWidgetView()

        const {
            getZoomNum
        } = usePhoneZoom()

        const selectBoxStyle = ref({})
        // 显示选中框
        const showSelectDox = computed(() => widgetIds.value.length > 1)
        const widgets = computed(() => widgetIds.value.map(id => widgetListFlat.value[id]))
        
        watch(
            [
                () => showSelectDox.value,
                () => widgetIds.value,
                () => widgets.value.map(item => ({ left: item?.widgetData?.eles?.style?.left, top: item?.widgetData?.eles?.style?.top }))
            ],
            ([newValue, newValue2, newValue3]) => {
                if (showSelectDox.value) {
                    nextTick(() => updateSelectBoxStyle())
                } else {
                    selectBoxStyle.value = {}
                }
            }
        )
        
        // 更新选中框样式
        const updateSelectBoxStyle = () => {
            const tops = []
            const bottoms = []
            const lefts = []
            const rights = []
            getWidgetViewDom(widgetIds.value).forEach(item => {
                const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = item
                tops.push(offsetTop)
                bottoms.push(offsetTop + offsetHeight)
                lefts.push(offsetLeft)
                rights.push(offsetLeft + offsetWidth)
            })
            const minTop = Math.min(...tops)
            const minLeft = Math.min(...lefts)
            selectBoxStyle.value = {
                top: minTop + 'px',
                left: minLeft + 'px',
                width: (Math.max(...rights) - minLeft) + 'px',
                height: (Math.max(...bottoms) - minTop) + 'px'
            }
        }

        // 选中框拖动
        const onSelectBoxDraggable = e => {
            e = e || window.event

            // 鼠标按下时坐标
            const { clientX: mouseX, clientY: mouseY } = e
            // 选中框的宽高和坐标
            let { left: domL, top: domT, width: domW, height: domH } = selectBoxStyle.value
            domL = parseInt(domL)
            domT = parseInt(domT)
            domW = parseInt(domW)
            domH = parseInt(domH)
            // 父容器宽高
            let { offsetWidth: parentW, offsetHeight: parentH } = parentDom.value
            parentW = parseInt(parentW)
            parentH = parseInt(parentH)

            // 更新后dom坐标
            let newDomL = domL
            let newDomT = domT
            let frame = null

            const doms = {}
            widgetIds.value.forEach(id => {
                const dom = getWidgetViewDom(id)
                doms[id] = {
                    dom,
                    position: {
                        top: parseInt(dom.style.top),
                        left: parseInt(dom.style.left),
                        newTop: parseInt(dom.style.top),
                        newLeft: parseInt(dom.style.left)
                    }
                }
            })

            let dragStatus = false
            // 窗口鼠标移动事件
            document.onmousemove = event => {
                dragStatus = true
                newDomL = parseInt(getZoomNum(event.clientX - mouseX) + domL)
                newDomT = parseInt(getZoomNum(event.clientY - mouseY) + domT)

                // 限制拖拽范围
                if (newDomL < 0) newDomL = 0
                if (newDomL + domW > parentW) newDomL = parentW - domW
                if (newDomT < 0) newDomT = 0
                if (newDomT + domH > parentH) newDomT = parentH - domH
                // 更新视图
                frame = requestAnimationFrame(() => {
                    updateSelectBoxStyle()
                    Object.values(doms).forEach(item => {
                        const left = parseInt(item.position.left) + newDomL - domL
                        const top = parseInt(item.position.top) + newDomT - domT
                        item.dom.style.cssText += `left:${left}px;top:${top}px;`
                        item.position.newTop = top
                        item.position.newLeft = left
                    })
                })
            }

            document.onmouseup = () => {
                // 更新数据
                widgetIds.value.forEach(id => {
                    const { widgetData } = widgetListFlat.value[id]
                    widgetData.eles.style.top = doms[id].position.newTop + 'px'
                    widgetData.eles.style.left = doms[id].position.newLeft + 'px'
                })
                if (dragStatus) onAddPageHistory()
                dragStatus = false
                cancelAnimationFrame(frame)
                document.onmousemove = null
                document.onmouseup = null
            }
        }
        // 选中框右键菜单
        const onSelectBoxContextmenu = e => {
            const { clientX, clientY } = e
            openWidgetContextmenu({
                left: clientX,
                top: clientY,
                widgetIds: widgetIds.value
            })
        }

        return {
            showSelectDox,
            selectBoxStyle,
            onSelectBoxDraggable,
            onSelectBoxContextmenu
        }
    }
})
</script>